////////////////////////////////////////////////////////////////////////////////
//
//  FLYING KIWI BV
//  Copyright 2010 Flying Kiwi BV
//  All Rights Reserved.
//
//  NOTICE: Flying Kiwi permits you to use, modify, and distribute this file
//  in accordance with the terms of the license agreement accompanying it.
//
////////////////////////////////////////////////////////////////////////////////
package plantool.modules.workplaces {
	//--------------------------------------------------------------------------
	//  Imports
	//--------------------------------------------------------------------------
	import flash.events.Event;
	import flash.utils.describeType;
	
	import kiwi.utils.Validation;
	
	import plantool.core.CoreApi;
	import plantool.data.Field;
	import plantool.data.FieldTypes;
	import plantool.data.QueryResult;
	import plantool.data.Table;
	import plantool.events.WorkplaceEvent;
	import plantool.modules.menu.data.MenuGroupData;
	import plantool.modules.menu.data.MenuItemData;
	import plantool.modules.orders.data.Orderplanning;
	import plantool.modules.users.data.UserHourData;
	import plantool.modules.users.data.UserHourTypes;
	import plantool.modules.workplaces.data.Workplace;
	import plantool.modules.workplaces.windows.WorkplaceWindow;
	
	//--------------------------------------------------------------------------
	//  [Metadata (Events, Style, Effects etc)]
	//--------------------------------------------------------------------------
	[Event(name="workplace_updated", type="plantool.events.WorkplaceEvent")]
	
	//--------------------------------------------------------------------------
	//  Class declaration
	//--------------------------------------------------------------------------
	public class WorkplaceApi extends CoreApi {
		//--------------------------------------------------------------------------
		//Class constants
		//--------------------------------------------------------------------------
		private static const NUM_TABLES:uint				= 2;
		
		//--------------------------------------------------------------------------
		//Class variables
		//--------------------------------------------------------------------------
		private static var _instance:WorkplaceApi	= null;
		private var _tblRdyCount:uint				= 0;
		private var _workplaceTable:Table			= null;
		private var _workplaceClass:Class			= Workplace;
		private var _textTable:Table				= null;
		
		//--------------------------------------------------------------------------
		//Class properties
		//--------------------------------------------------------------------------
		public function get workplaceClass():Class {
			return _workplaceClass;
		}
		public function get workplaceTable():Table {
			return _workplaceTable;
		}
		
		//--------------------------------------------------------------------------
		//Constructor and Destructor
		//--------------------------------------------------------------------------
		public function WorkplaceApi(pvt:PrivateConstructorClass) {
			super();
			
			//create workplace-table fields
			_workplaceTable = new Table("workplaces");
			_workplaceTable.addField(new Field("name"	, FieldTypes.VARCHAR));
			
			//create text-table
			_textTable = new Table('workplace_texts');
			_textTable.addField(new Field("text"		, FieldTypes.TEXT));
			_textTable.addField(new Field("date"		, FieldTypes.DATE));
			_textTable.addField(new Field("workplace"	, FieldTypes.INT));
			
			//add menu
			var group:MenuGroupData = new MenuGroupData();
			group.title				= "Machines";
			group.addItem(new MenuItemData("Overzicht", showListForm));
			group.addItem(new MenuItemData("Toevoegen", showForm));
			menuApi.addGroup(group);
		}
		
		//--------------------------------------------------------------------------
		//Class methods
		//--------------------------------------------------------------------------
		public static function getInstance():WorkplaceApi {
			//check if instance exists, if not create one
			if (!Validation.isSet(_instance)) {
				_instance = new WorkplaceApi(new PrivateConstructorClass());
			}
			
			//return instance
			return _instance;
		}
		
		private function createWorkplace(workplace:Workplace, onCompleteHandler:Function, onErrorHandler:Function):void {
			//create complete handler
			var onComplete_createWorkplace:Function = function(result:QueryResult):void {
				//pass result to complete handler
				if (Validation.isSet(onCompleteHandler)) {
					onCompleteHandler(result);
				}
				
				//inform that we're updated
				dispatchEvent(new WorkplaceEvent(WorkplaceEvent.WORKPLACE_UPDATED, result.insertRowId));
			}
			
			//get all field to save to database
			var varList:XMLList = flash.utils.describeType(workplace)..accessor;
			
			//create the insert query
			//TODO:Generalize the creation insert-querys
			var fields:String	= "(";
			var values:String	= " VALUES(";
			var cnt:uint		= 0;
			for (var i:uint = 0; i < varList.length(); i++) {
				//skip the field 'id'
				if (varList[i].@name != "id") {
					//add field separator
					if (cnt > 0) {
						fields += ", ";
						values += ", ";
					}
					
					fields += "`" + varList[i].@name + "`";
					values += "'" + workplace[varList[i].@name] + "'";
					
					//increase field counter
					cnt++;
				}
			}
			
			//close query values and fields
			fields += ")";
			values += ")";
			
			//create query
			var query:String = "INSERT INTO `workplaces`" + fields + values;
			
			//create the user
			databaseManager.query(query, onComplete_createWorkplace, onErrorHandler);
		}
		
		private function initSettings():void {
		}
		
		private function onComplete_createTable():void {
			//table ready
			_tblRdyCount++;
			
			//all tables ready?
			if (_tblRdyCount == NUM_TABLES) {
				//init settings
				initSettings();
				
				//inform listeners that we're complete
				dispatchEvent(new Event(Event.COMPLETE));
			}
		}
		
		private function updateWorkplace(workplace:Workplace, onCompleteHandler:Function, onErrorHandler:Function):void {
			//create complete handler
			var onComplete_updateWorkplace:Function = function(result:QueryResult):void {
				//pass result to complete handler
				if (Validation.isSet(onCompleteHandler)) {
					onCompleteHandler(result);
				}
				
				//inform that we're updated
				dispatchEvent(new WorkplaceEvent(WorkplaceEvent.WORKPLACE_UPDATED, workplace.id));
			}
			
			//get all field to save to database
			var varList:XMLList = flash.utils.describeType(workplace)..accessor;
			
			//create the update query
			//TODO:Generalize the creation update-querys
			var values:String	= "";
			var cnt:uint		= 0;
			for (var i:uint = 0; i < varList.length(); i++) {
				//skip the field 'id'
				if (varList[i].@name != "id") {
					//add field separator
					if (cnt > 0) {
						values += ", ";
					}
					
					//set values
					values += "`" + varList[i].@name + "`='" + workplace[varList[i].@name] + "'";
					
					//increase field counter
					cnt++;
				}
			}
			
			//create query
			var query:String = "UPDATE `workplaces` SET " + values + " WHERE `id`=" + workplace.id;
			
			//create the user
			databaseManager.query(query, onComplete_updateWorkplace, onErrorHandler);
		}
		
		public function getWorkplaceHours(workplaceId:uint, from:Date, till:Date, onCompleteHandler:Function, onErrorHandler:Function, userdata:* = null):void {
			databaseManager.query("SELECT `id`, `user_id`, `type`, `related_id`, " + databaseManager.formatDateField("`timestamp_from`") + " as `from`, " + databaseManager.formatDateField("`timestamp_till`") + " as `till` FROM `user_hours` WHERE `related_id`=" + workplaceId.toString() + " AND (`from` >= " + databaseManager.formatDateField(databaseManager.formatDate(from)) + " AND `till` <= " + databaseManager.formatDateField(databaseManager.formatDate(till)) + ")", onCompleteHandler, onErrorHandler, UserHourData, userdata);
		}
		
		public function getAllWorkplaceHours(from:Date, till:Date, onCompleteHandler:Function, onErrorHandler:Function, userdata:* = null):void {
			databaseManager.query("SELECT `id`, `user_id`, `type`, `related_id`, " + databaseManager.formatDateField("`timestamp_from`") + " as `from`, " + databaseManager.formatDateField("`timestamp_till`") + " as `till` FROM `user_hours` WHERE (`from` >= " + databaseManager.formatDateField(databaseManager.formatDate(from)) + " AND `till` <= " + databaseManager.formatDateField(databaseManager.formatDate(till)) + ")", onCompleteHandler, onErrorHandler, UserHourData, userdata);
		}
		
		public function getOrderPlanningByID(planningId:uint, onCompleteHandler:Function, onErrorHandler:Function):void {
			//create oncomplete function to store users
			var onGet_orderPlanning:Function = function(result:QueryResult):void {
				//call oncomplete handler with result
				if (Validation.isSet(onCompleteHandler)) {
					onCompleteHandler(result);
				}
			}
			
			//get all orders
			var query:String = "SELECT `id`, `order_id`, `orderrow_id`, `related_id`, " + databaseManager.formatDateField("`timestamp`") + " as `date`, `time`, `ready`  FROM `order_planning` WHERE `id` = " + planningId.toString();
			databaseManager.query(query, onGet_orderPlanning, onErrorHandler, Orderplanning);
		}
		
		public function getPlannedOrders(from:Date, till:Date, onCompleteHandler:Function, onErrorHandler:Function, userdata:* = null):void {
			databaseManager.query("SELECT `id`, `order_id`, `orderrow_id`, `related_id`, " + databaseManager.formatDateField("`timestamp`") + " as `date`, `time`, `ready`  FROM `order_planning` WHERE (`date` >= " + databaseManager.formatDateField(databaseManager.formatDate(from)) + " AND `date` <= " + databaseManager.formatDateField(databaseManager.formatDate(till)) + ")", onCompleteHandler, onErrorHandler, Orderplanning, userdata);
		}
		
		public function getWorkplaces(onCompleteHandler:Function, onErrorHandler:Function):void {
			//get all users
			databaseManager.query("SELECT * FROM `workplaces`", onCompleteHandler, onErrorHandler, _workplaceClass);
		}
		
		public function saveWorkpace(workplace:Workplace, onCompleteHandler:Function, onErrorHandler:Function):void {
			//if id > 0 update the user, otherwise create a new user
			if (workplace.id > 0) {
				updateWorkplace(workplace, onCompleteHandler, onErrorHandler);
			} else {
				createWorkplace(workplace, onCompleteHandler, onErrorHandler);
			}
		}
		
		public override function install():void {
			//check table workplaces
			databaseManager.createTable(_workplaceTable, onComplete_createTable);
			//check table workplace-texts
			databaseManager.createTable(_textTable, onComplete_createTable);
		}
		
		public function showForm(workplace:Workplace = null):void {
			var window:WorkplaceWindow = new WorkplaceWindow();
			window.show();
		}
		
		public function showListForm():void {
			
		}
	}
}

//--------------------------------------------------------------------------
//END OF PACKAGE
//Define the PrivateConstructorClass here so an instance cannot be by anyone
//except for the class defined in the above package
//--------------------------------------------------------------------------
class PrivateConstructorClass {
	//--------------------------------------------------------------------------
	//Constructor and Destructor
	//--------------------------------------------------------------------------
	public function PrivateConstructorClass() {
	}
}